`include "../codigo/Decode.v"
`include "Registers.v"
module test_Decode();

    // ********** Instanciacao dos módulos ********** //
    Decode decode(r_clock,
                  r_reset,
                  r_fw_if_id_stall,
                  r_if_id_instrucao,
                  r_if_id_proximopc,
                  w_id_if_selfontepc,
                  w_id_if_rega,
                  w_id_if_pcimd2ext,
                  w_id_if_pcindex,     
                  w_id_if_seltipopc,
                  w_id_ex_selalushift,
                  w_id_ex_selimregb,
                  w_id_ex_selsarega,
                  w_id_ex_aluop,
                  w_id_ex_unsig,
                  w_id_ex_shiftop,
                  w_id_ex_shiftamt,
                  w_id_ex_rega,
                  w_id_ex_msm,
                  w_id_ex_msl,
                  w_id_ex_readmem,
                  w_id_ex_writemem,
                  w_id_ex_mshw,
                  w_id_ex_lshw,
                  w_id_ex_regb,
                  w_id_ex_imedext,
                  w_id_ex_proximopc,
                  w_id_ex_selwsource,
                  w_id_ex_regdest,
                  w_id_ex_writereg,
                  w_id_ex_writeov,
                  w_id_fw_regdest,
                  w_id_fw_load,
                  w_id_fw_addra,
                  w_id_fw_addrb,
                  w_id_fw_rega,
                  w_id_fw_regb,
                  r_fw_id_rega,
                  r_fw_id_regb,
                  w_id_reg_addra,
                  w_id_reg_addrb,
                  w_reg_id_dataa, // Vem de Registradores
                  w_reg_id_datab, // Vem de Registradores
                  w_id_reg_ena,
                  w_id_reg_enb );
    
    Registers registers(r_reset,
                        w_id_reg_ena,
                        w_id_reg_addra,
                        w_reg_id_dataa,
                        w_id_reg_enb,
                        w_id_reg_addrb,
                        w_reg_id_datab,
                        r_enc,
                        r_addrc,
                        r_datac);

    // ********** Declarações ********** //

    reg        r_clock;
    reg        r_reset;
    reg        r_fw_if_id_stall;

    // Fetch
    reg  [31:0] r_if_id_instrucao;
    reg  [31:0] r_if_id_proximopc;
    wire        w_id_if_selfontepc;
    wire [31:0] w_id_if_rega;
    wire [31:0] w_id_if_pcimd2ext;
    wire [31:0] w_id_if_pcindex;
    wire [1:0]  w_id_if_seltipopc;

    // Execute
    wire        w_id_ex_selalushift;
    wire        w_id_ex_selimregb;
    wire        w_id_ex_selsarega;
    wire [2:0]  w_id_ex_aluop;
    wire        w_id_ex_unsig;
    wire [1:0]  w_id_ex_shiftop;
    wire [4:0]  w_id_ex_shiftamt;
    wire [31:0] w_id_ex_rega;
    wire [2:0]  w_id_ex_msm;
    wire [2:0]  w_id_ex_msl;
    wire        w_id_ex_readmem;
    wire        w_id_ex_writeme;
    wire        w_id_ex_mshw;
    wire        w_id_ex_lshw;
    wire [31:0] w_id_ex_regb;
    wire [31:0] w_id_ex_imedext;
    wire [31:0] w_id_ex_proximopc;
    wire [2:0]  w_id_ex_selwsource;
    wire [4:0]  w_id_ex_regdest;
    wire        w_id_ex_writere;
    wire        w_id_ex_writeov; 
 
    // Forward   
    wire [4:0]  w_id_fw_regdest;
    wire        w_id_fw_load;
    wire [4:0]  w_id_fw_addra;
    wire [4:0]  w_id_fw_addrb;
    wire [31:0] w_id_fw_rega;
    wire [31:0] w_id_fw_regb;
    reg  [31:0] r_fw_id_rega;
    reg  [31:0] r_fw_id_regb;

    // Registers
    wire [4:0]  w_id_reg_addra;
    wire [4:0]  w_id_reg_addrb;
    wire [31:0] w_reg_id_dataa; // conecta disp.
    wire [31:0] w_reg_id_datab; // conecta disp.
    wire        w_id_reg_ena;
    wire        w_id_reg_enb; 
    reg         r_enc;   // Complemento para dispositivo.
    reg  [4:0]  r_addrc; // Complemento para dispositivo.
    reg  [31:0] r_datac; // Complemento para dispositivo.

    // ********* Inicio ******** //
    initial begin
        
        // Header.
        #1 $display("\n========================================================================\n");
        #1 $display("Resumo: Todos os testes sao feitos para verificar se os sinais estao sendo\n repassados de acordo para os diversos modulos ligados ao Decode.");
        #1 $display("\n========================================================================\n");
        
        // Comece aqui.
        // Primeiro teste: Testa se o proximopc é repassado.
        #1 $display("########################### Teste 1: ProximoPC ############################");
        #1 $display("Teste:  if_id_proximopc\n\tid_ex_proximopc\n\tfw_if_id_stall");
        #1 $display("Entrada: if_id_proximopc = 40\n\t fw_if_id_stall = 0");
        #1 $display("Saida Esperada: id_ex_proximopc = 40");
       
        #1 r_clock = 1;
        #1 r_if_id_proximopc = 32'd40;
        #1 r_fw_if_id_stall = 1'b0;
        #1 r_clock = 0;
      
        #1 $display("Resultado: id_ex_proximopc: %d ; ", decode.id_ex_proximopc);
        #1 $display("###########################################################################");

        // Segundo teste: Dado uma operação, verifica os sinais repassados
        // ao execute.
        #1 $display("############################ Teste 2: Execucao ############################");
        #1 $display("Teste:  if_id_instrucao\n\tid_ex_selalushift\n\tid_ex_selimregb\n\tid_ex_selsarega\n\tid_ex_aluop\n\tid_ex_unsig\n\tid_ex_shiftop\n\tid_ex_shiftamt\n\tid_ex_rega\n\tid_ex_msm\n\tid_ex_msl\n\tid_ex_readmem\n\tid_ex_writemem\n\tid_ex_mshw\n\tid_ex_lshw\n\tid_ex_regb\n\tid_ex_imedext\n\tid_ex_proximopc\n\tid_selwsource\n\tid_ex_regdest\n\tid_ex_writereg\n\tid_ex_writeov\n\t");
        #1 $display("Entrada: if_id_instrucao = 603914243\n\t fw_if_id_stall = 0");
        #1 $display("Saida Esperada: id_ex_proximopc = 40\n\tid_ex_selalushift = 0\n\tid_ex_selimregb = 1\n\tid_ex_selsarega = 0\n\tid_ex_aluop = 010\n\tid_ex_unsig = 0\n\tid_ex_shiftop = x\n\tid_ex_shiftamt = 00000\n\tid_ex_rega = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n\tid_ex_msm = xxx\n\tid_ex_msl = xxx\n\tid_ex_readmem = 0\n\tid_ex_writemem = 0\n\tid_ex_mshw = x\n\tid_ex_lshw = x\n\tid_ex_regb = x\n\tid_ex_imedext = 00000000000000000010001111111111\n\tid_ex_proximopc = 40\n\tid_ex_selwsource = 000\n\tid_ex_regdest = 11111\n\tid_ex_writereg = 1\n\tid_ex_writeov = 0");
       
        #1 r_clock = 1;
        #1 r_if_id_proximopc = 32'd40;
        #1 r_fw_if_id_stall = 1'b0;
        #1 r_if_id_instrucao = 32'd603914243;
        #1 r_clock = 0;
      
        #1 $display("Resultado: id_ex_proximopc: %d\n\tid_ex_selalushift = %b\n\tid_ex_selimregb = %b\n\tid_ex_selsarega = %b\n\tid_ex_aluop = %b\n\tid_ex_unsig = %b\n\tid_ex_shiftop = %b\n\tid_ex_shiftamt = %b\n\tid_ex_rega = %b\n\tid_ex_msm = %b\n\tid_ex_msl = %b\n\tid_ex_readmem = %b\n\tid_ex_writemem = %b\n\tid_ex_mshw = %b\n\tid_ex_lshw = %b\n\tid_ex_regb = %b\n\tid_ex_imedext = %b\n\tid_ex_proximopc = %d\n\tid_ex_selwsource = %b\n\tid_ex_regdest = %b\n\tid_ex_writereg = %b\n\tid_ex_writeov = %b\n\t ", decode.id_ex_proximopc,decode.id_ex_selalushift,decode.id_ex_selimregb,decode.id_ex_selsarega,decode.id_ex_aluop,decode.id_ex_unsig,decode.id_ex_shiftop,decode.id_ex_shiftamt,decode.id_ex_rega,decode.id_ex_msm,decode.id_ex_msl,decode.id_ex_readmem,decode.id_ex_writemem,decode.id_ex_mshw,decode.id_ex_lshw,decode.id_ex_regb,decode.id_ex_imedext,decode.id_ex_proximopc,decode.id_ex_selwsource,decode.id_ex_regdest,decode.id_ex_writereg,decode.id_ex_writeov);
        #1 $display("############################################################################");

        // Terceiro teste: Verifica se os dados estão chegando dos registradores.
        #1 $display("########################## Teste 3: Registradores ##########################");
        #1 $display("Teste: reset,reg_id_dataa\n\treg_id_datab\n\tid_reg_addra\n\tid_reg_addrb\n\tid_reg_ena\n\tid_reg_enb");
        #1 $display("Entrada: if_id_proximopc = 40\n\t fw_if_id_stall = 0\n\tif_id_instrucao = 32'd603914243");
        #1 $display("Saida Esperada: id_ex_proximopc = 40\n\treg_id_dataa = 0\n\treg_id_datab = 0\n\tid_reg_addra = 11111\n\tid_reg_addrb = 11111\n\tid_reg_ena = 1\n\tid_reg_enb = 1 ");
      
        #1 r_reset = 0;
        #1 r_reset = 1;
        #1 r_reset = 0;
        #1 r_reset = 1; 
        #1 r_clock = 1;
        #1 r_if_id_proximopc = 32'd40;
        #1 r_fw_if_id_stall = 1'b0;
        #1 r_if_id_instrucao = 32'd603914243;       
        #1 r_clock = 0;
      
        #1 $display("Resultado: reg_id_dataa = %b\n\treg_id_datab = %b\n\tid_reg_addra = %b\n\tid_reg_addrb = %b\n\tid_reg_ena = %b\n\tid_reg_enb = %b", decode.reg_id_dataa,decode.reg_id_datab,decode.id_reg_addra,decode.id_reg_addrb,decode.id_reg_ena,decode.id_reg_enb);
        #1 $display("############################################################################");

        // Quarto teste: Verifica os sinais para o forward.
        #1 $display("############################ Teste 4: Forwarding ###########################");
        #1 $display("Teste: id_fw_regdest\n\tid_fw_load\n\tid_fw_addra\n\tid_fw_addrb\n\tid_fw_rega\n\tid_fw_regb\n\tfw_id_rega\n\tfw_id_regb\n\tid_ex_rega\n\tid_ex_regb");
        #1 $display("Entrada: fw_if_id_stall = 0\n\tif_id_instrucao = 32'd603914243");
        #1 $display("Saida Esperada: id_fw_regdest = 11111\n\tid_fw_load = 0\n\tid_fw_addra = 11111\n\tid_fw_addrb = 11111\n\tid_fw_rega = 0\n\tid_fw_regb = 0\n\tfw_id_rega = 5\n\tfw_id_regb = 5\n\tid_ex_rega = 5\n\tid_ex_regb = 5");
      
        #1 r_reset = 0;
        #1 r_reset = 1;
        #1 r_reset = 0;
        #1 r_reset = 1; 
        #1 r_clock = 1;
        #1 r_fw_id_rega = 32'd5;
        #1 r_fw_id_regb = 32'd5;
        #1 r_if_id_proximopc = 32'd40;
        #1 r_fw_if_id_stall = 1'b0;
        #1 r_if_id_instrucao = 32'd603914243;       
        #1 r_clock = 0;
 
        #1 $display("Saida: id_fw_regdest = %b\n\tid_fw_load = %b\n\tid_fw_addra = %b\n\tid_fw_addrb = %b\n\tid_fw_rega = %b\n\tid_fw_regb = %b\n\tfw_id_rega = %d\n\tfw_id_regb = %d\n\tid_ex_rega = %d\n\tid_ex_regb = %d",decode.id_fw_regdest,decode.id_fw_load,decode.id_fw_addra,decode.id_fw_addrb,decode.id_fw_rega,decode.id_fw_regb,decode.fw_id_rega,decode.fw_id_regb,decode.id_ex_rega,decode.id_ex_regb);
      
        #1 $display("############################################################################");

        // Quinto teste: Verifica os sinais para Fetch.
        #1 $display("############################## Teste 5: Fetch ##############################");
        #1 $display("Teste: id_if_selfontepc\n\tid_if_rega\n\tid_if_pcimd2ext\n\tid_if_pcindex\n\tid_if_seltipopc");
        #1 $display("Entrada: fw_if_id_stall = 0\n\tif_id_instrucao = 32'd603914243");
        #1 $display("Saida Esperada: id_if_selfontepc = 0\n\tid_if_rega = 0\n\tid_if_pcimd2ext = 00000000000000000000000000110100\n\tid_if_pcindex = 000011111111000000000000001100\n\tid_if_seltipopc = 11");
      
        #1 r_reset = 0;
        #1 r_reset = 1;
        #1 r_reset = 0;
        #1 r_reset = 1; 
        #1 r_clock = 1;
        #1 r_fw_id_rega = 32'd5;
        #1 r_fw_id_regb = 32'd5;
        #1 r_if_id_proximopc = 32'd40;
        #1 r_fw_if_id_stall = 1'b0;
        #1 r_if_id_instrucao = 32'd603914243;       
        #1 r_clock = 0;
 
        #1 $display("Saida: proximopc = %b\n\tid_if_selfontepc = %b\n\tid_if_rega = %b\n\tid_if_pcimd2ext = %b\n\tid_if_pcindex = %b\n\tid_if_seltipopc = %b",decode.if_id_proximopc,decode.id_if_selfontepc,decode.id_if_rega,decode.id_if_pcimd2ext,decode.id_if_pcindex,decode.id_if_seltipopc);
      
        #1 $display("############################################################################");



    end
endmodule 
